/**
 * Copyright 2011 Mathieu Magnaudet
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package edu.enac.geoapp.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geotools.map.MapLayer;

/**
 * Data bundle containing: - a list of background MapLayer - a
 *         list of meteorological MapLayer - the corresponding meta data
 * @author mathieu 
 */
public class DisplayableView {
	private List<MapLayer> backgroundLayerList;
	private ArrayList<MapLayer>[] data = null;
	private Map<String, String> metadata;

	/**
	 * @return the backgroundLayerList
	 */
	public List<MapLayer> getBackgroundLayerList() {
		return backgroundLayerList;
	}

	private int nbOfDate;
	private boolean superposeLayers;

	/**
	 * Constructor
	 * 
	 * @param nbOfDate
	 *            The number of forecasts in the meteorological data. If
	 *            nbOfDate = 0 the this view will be considered as having no
	 *            data
	 * @param superposeLayers
	 *            if true, all the meteorological layers will be displayed in
	 *            the same time. If false, the user will have the possibility to
	 *            navigate between the layers via the buttons of the GUI
	 */
	@SuppressWarnings("unchecked")
	public DisplayableView(int nbOfDate, boolean superposeLayers) {
		this.nbOfDate = nbOfDate;
		this.superposeLayers = superposeLayers;
		backgroundLayerList = new ArrayList<MapLayer>();

		if (nbOfDate > 0) {
			data = new ArrayList[nbOfDate];
			metadata = new HashMap<String, String>();

			for (int i = 0; i < nbOfDate; i++) {
				data[i] = new ArrayList<MapLayer>();
			}
		}
	}

	/**
	 * Adds a layer to the list of the background layers
	 * 
	 * @param layer
	 *            the layer to add
	 */
	public void addBackgroundLayer(MapLayer layer) {
		backgroundLayerList.add(layer);
	}

	/**
	 * Removes a layer to the list of the background layers
	 * 
	 * @param layer
	 *            the layer to remove
	 */
	public void removeBackgroundLayer(MapLayer layer) {
		backgroundLayerList.remove(layer);
	}

	/**
	 * Adds a meteorological layer to the list of data layers
	 * 
	 * @param dateIndex
	 *            The date index of the forecast
	 * @param layer
	 *            The layer to add
	 * @throws IllegalAccessException
	 *             if the view has been created as having no data (i. e.
	 *             nbOfDate = 0)
	 */
	public void addData(int dateIndex, MapLayer layer)
			throws IllegalAccessException {
		if (!hasData()) {
			throw new IllegalAccessException(
					"You can't add data to this object");
		}
		data[dateIndex].add(layer);
	}

	/**
	 * Adds a meteorological layer to the list of data layers
	 * 
	 * @param dateIndex
	 *            The date index of the forecast
	 * @param layer
	 *            The layer to add
	 * @param metadata
	 *            The associated meta data
	 * @throws IllegalAccessException
	 *             if the view has been created as having no data (i. e.
	 *             nbOfDate = 0)
	 */
	public void addData(int dateIndex, MapLayer layer, String metadata)
			throws IllegalAccessException {
		addData(dateIndex, layer);
		this.metadata.put(layer.getTitle(), metadata);
	}

	/**
	 * Returns the meta data of a meteorological layer 
	 * @param layerTitle the name of the layer
	 * @return the meta data
	 */
	public String getMetadata(String layerTitle) {
		return metadata.get(layerTitle);
	}

	/**
	 * Returns the meteorological layers corresponding to the specified date index
	 * @param dateIndex the date index
	 * @return the list of layers
	 */
	public List<MapLayer> getDataByDate(int dateIndex) {
		return data[dateIndex];
	}

	/**
	 * @return the nbOfDate
	 */
	public int getNbOfDates() {
		return nbOfDate;
	}

	/**
	 * 
	 * @return true if this view has meteorological data false otherwise
	 */
	public boolean hasData() {
		return data != null;
	}

	/**
	 * @return true if the meteorological layers must be superposed 
	 */
	public boolean isSuperposeLayers() {
		return superposeLayers;
	}

	/**
	 * 
	 * @return  all the meteorological data as an array of MapLayer lists
	 */
	public List<MapLayer>[] getData() {
		return data;
	}
}
